﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Ccr.Core;
using XcoAppSpaces.Contracts.Exceptions;
using XcoAppSpaces.Core;

namespace XcoAppSpaces.Discovery
{
	public static class XcoAppSpaceExtensions
	{
		public static T DiscoverWorker<T>(this IXcoAppSpace space)
			where T : IPort, new()
		{
			return space.DiscoverWorker<T>(null);
		}

		public static T DiscoverWorker<T>(this IXcoAppSpace space, string workerName)
			where T : IPort, new()
		{
			var discoService = space.Info.ServiceRegistry.Resolve<IXcoDiscoveryService>();
			if (discoService == null)
				throw new XcoDiscoveryException("Discovery service could not be found.");
			
			var result = discoService.Resolve<T>(workerName);
			if (result.Result == DiscoveryResult.WorkerNotFound)
				throw new XcoDiscoveryException("Worker with type " + typeof(T) + (workerName != null ? (" and Name " + workerName) : "") + " could not be found.");
			if (result.Result == DiscoveryResult.WorkerFoundLocal)
				return space.Resolve<T>(workerName);
			var address = (workerName != null ? (result.WorkerAddress + "/" + workerName) : result.WorkerAddress);
			return space.ConnectWorker<T>(address);
		}

		public static bool HasDiscoveryService(this IXcoAppSpace space)
		{
			return (space.Info.ServiceRegistry.Resolve<IXcoDiscoveryService>() != null);
		}
	}
}
